/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2024 INRIA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef NM_MUMPS_h
#define NM_MUMPS_h

#include "NumericsFwd.h"    // for NumericsMatrix
#include "SiconosConfig.h"  // for BUILD_AS_CPP, WITH_MUMPS // IWYU pragma: keep

#if defined(__cplusplus) && !defined(BUILD_AS_CPP)
extern "C" {
#endif

#ifdef WITH_MUMPS
#include <dmumps_c.h>

#ifndef MUMPS_INT
#define MUMPS_INT int
#endif

#define JOB_INIT -1
#define JOB_END -2
#define USE_COMM_WORLD -987654
#define ICNTL(I) icntl[(I)-1]
#define CNTL(I) cntl[(I)-1]
#define RINFOG(I) rinfog[(I)-1]

void NM_MUMPS_set_irn_jcn(NumericsMatrix* A);

/** Get (and create if necessary) the config data for MUMPS.
 *
 *  \param A, the matrix to be factorized.
 */
DMUMPS_STRUC_C* NM_MUMPS_id(NumericsMatrix* A);

/** Set the config data for MUMPS.
 *
 *  \param A the matrix,
 *  \param id the config data,
 *  \return the DMUMPS_STRUC_C config.
 */
void NM_MUMPS_set_id(NumericsMatrix* A, DMUMPS_STRUC_C* id);

/** Set control parameters (mpi communicator, verbosity).
 *
 *  \param A, the matrix holding the MUMPS config.
 */
void NM_MUMPS_set_control_params(NumericsMatrix* A);

/** Set control of parallelism.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param par, value of MUMPS par, see MUMPS documentation.
 */
void NM_MUMPS_set_par(NumericsMatrix* A, int par);

/** Set matrix symetry.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param sym, value for matrix symmetry, see MUMPS documentation.
 */
void NM_MUMPS_set_sym(NumericsMatrix* A, int sym);

/** Set icntl control.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param index, the fortran index in the icntl array,
 *  \param val, the new integer value.
 */
void NM_MUMPS_set_icntl(NumericsMatrix* A, unsigned int index, int val);

/** Return icntl value.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param index, the FORTRAN index in the icntl array,
 *  \return the ICNTL(index) value.
 */
int NM_MUMPS_icntl(NumericsMatrix* A, unsigned int index);

/** Set cntl control.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param index, the FORTRAN index in the cntl array,
 *  \param val the new double value.
 */
void NM_MUMPS_set_cntl(NumericsMatrix* A, unsigned int index, double val);

/** Return cntl value.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param index, the FORTRAN index in the cntl array.
 *  \return the CNTL(index) value.
 */
double NM_MUMPS_cntl(NumericsMatrix* A, unsigned int index);

/** Set matrix before factorization.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param nrhs, the number of right hand side.
 *  \param b, a pointer on double values of the right hand side.
 */
void NM_MUMPS_set_matrix(NumericsMatrix* A);

/** Set dense right hand side.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param nrhs, the number of right hand side.
 *  \param b, a pointer on double values of the right hand side.
 */
void NM_MUMPS_set_dense_rhs(NumericsMatrix* A, unsigned int nrhs, double* b);

/** Set sparse right hand side.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param B, the matrix holding the right hand side.
 *  B is converted to csc if not already stored in this
 *  representation.
 */
void NM_MUMPS_set_sparse_rhs(NumericsMatrix* A, NumericsMatrix* B);

/** Set MUMPS verbosity.
 *
 *  \param A, the matrix holding the MUMPS config,
 *  \param verbosity, an integer: 0 for silent or 1 for verbose.
 */
void NM_MUMPS_set_verbosity(NumericsMatrix* A, unsigned int verbosity);

/** Set some default parameters for the solve.
 *
 *  \param A the matrix holding the MUMPS config
 */
void NM_MUMPS_set_default_params(NumericsMatrix* A);

/** Display extra information about the solve
 *
 *  \param A the matrix holding the MUMPS config
 */
void NM_MUMPS_extra_display(NumericsMatrix* A);

/** call MUMPS. If several MPI process are running, only rank=0
 *  returns after sending the job to all the process, the others will
 *  wait for other job, until job=0.
 *
 *  \param A the matrix holding the MUMPS config
 *  \param job the int that specify the MUMPS job.  job=0 makes all process return.
 */
void NM_MUMPS(NumericsMatrix* A, int job);

/** Free the config data for MUMPS
 *
 *  \param param p a pointer on the linear solver parameters
 */
void NM_MUMPS_free(void* p);

#endif /* WITH_MUMPS */
/** copy MUMPS id if compiled WITH_MUMPS, otherwise do nothing.
 *
 *  \param A the source NumericsMatrix
 *  \param B the destination NumericsMatrix
 */
void NM_MUMPS_copy(const NumericsMatrix* A, NumericsMatrix* B);

#if defined(__cplusplus) && !defined(BUILD_AS_CPP)
}
#endif

#endif
